<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vm于vc</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <h1>{{msg}}</h1>
    <user></user>
</div>

<script>

    //这个不是给Vue扩展counter属性
    //这个是给 "Vue的原型对象"扩展一个counter属性
    Vue.prototype.counter = 2000

    //创建组件
    const user = Vue.extend({
        template : `
            <div>
                <h1>user组件</h1>
            </div>
        `,
        mounted(){
            //this是VueComponent实例
            //user是什么 呢? 是一个全新的构造函数 VueComponent构造函数
            console.log('vc' , this)
            //为什么要这样设计?为了代码复用
            //底层的实现原理:
            // VueComponent.prototype.__proto__ = Vue.prototype
            console.log('vc.counter' , this.counter)
            //这个访问不了,因为msg是vm实例上的属性
            console.log('vc.msg' ,  this.msg)
        }
    })


    console.log(user)

    //vm
     const vm = new Vue({
         el: '#app',
         //Model M
         data: {
             msg: 'vm与vc'
         },
         components : {
             //注册组件
             user
         },
         mounted() {
             //this是Vue实例
            console.log('vm' , this)
         }
     })


    //创建一个构造函数
    // function test(){
    //     var Sub = function User(){
    //         this.name = 'admin'
    //     }
    //     return Sub
    // }
    // let a = test()
    // //通过构造函数创建对象
    // console.log(new a())
    // console.log(a)
    //
    // let b = test()
    // console.log(b)
    //
    // //一个构造函数创建出来的是两个不同的对象
    // console.log(a === b)

    //构造函数 (函数本身又是一种类型,代表Vip类型)
    function Vip(){}

    //Vip类型/Vip构造函数,有一个 prototype属性
    //这个prototype属性可以称为:显式的原型属性
    //通过这个显示的原型属性可以获取:原型对象
    //获取Vip的原型对象
    let x = Vip.prototype
    console.log(x)

    //通过Vip可以创建实例
    let a = new Vip()
    // let b = new Vip()
    // let c = new Vip()

    //对于实例来说，都有一个隐式的原型属性:__proto__
    //注意:显示的(建议程序员使用的).隐式的(不建议程序员使用的)
    //这种方式也可以获取到Vip的原型对象
    let y = a.__proto__
    // b.__proto__
    // c.__proto__
    console.log(y)

    //原型对象只有一个，其实原型对象都是共享的
    console.log(x === y) //true

    //这个不是给Vip扩展属性
    //是在给 "Vip的原型对象" 扩展属性
    Vip.prototype.counter = 1000

    console.log(Vip.prototype.counter)

    //通过a实例可以访问这个扩展的counter属性吗?可以访问.为什么?原理是啥?
    //访问原理:首先去a实例上找counter属性,如果a实例没有counter属性的话,会沿着__proto__这个原型对象去找
    //下面代码看起来表面上是a有一个counter属性,实际上不是a实例上的属性,是a实例对应的原型对象上的属性counter
    console.log(a.counter)
    console.log(a.__proto__.counter)



</script>

</body>
</html>
